package de.mnit.basis.sys.datei;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import de.mnit.basis.daten.FilterText;
import de.mnit.basis.fehler.Fehler;
import de.mnit.basis.fehler.system.F_Sys_Datei;
import de.mnit.basis.fehler.system.F_Sys_InOut;

/**
 * @author Michael Nitsche
 *
 * TODO Nochmal Testen und evtl. so umbauen, daß nicht permanent ein File gehalten wird. Evtl. sperrt dieses z.B. rename oder del
 */
public class DSDatei extends A_DS_Element implements S_Datei {

	public DSDatei(File f) {
		Fehler.objekt.wenn_Null(f);
		this.file=f;
	}

	public DSDatei(String pfad) {
		this(new File(pfad));
	}


	public static DSDatei neu(File f) {
		return new DSDatei(f);
	}

	public static DSDatei neu(String pfad) {
		return new DSDatei(pfad);
	}


	public FileOutputStream schreiben() throws F_Sys_Datei {
		try {
			return new FileOutputStream(this.file);
		}
		catch(FileNotFoundException e) {
			throw Fehler.weitergeben(e, "Datei nicht gefunden");
		}
	}

	public FileInputStream lesen() throws F_Sys_Datei {
		try {
			return new FileInputStream(this.file);
		}
		catch(FileNotFoundException e) {
			throw Fehler.weitergeben(e, "Datei nicht gefunden");
		}
	}

	public String gEndung() {
		String name=this.file.getName();
		String endung=name.replaceFirst("^.*\\.(.*)$", "$1");
		if(endung.length()>10 || name.equals(endung))
			return ""; //z.B.: .properties
		return endung;
	}

	public void sEndung(String s) {
		s.replaceFirst("^\\.+", "");
		String suffix=gEndung();
		String pfad=this.gPfadKomplett();
		pfad=FilterText.teil(0-suffix.length()-1, true, pfad);
		pfad=pfad.replaceFirst("\\.+$", "");
		this.file=new File(pfad+"."+s);
	}

	public long gGroesse() {
		return this.file.length();
	}

	public String gNameKomplett() {
		return this.file.getName();
	}

	public String gName() {
		return this.file.getName().replaceFirst("^(.*)\\..*$", "$1");
	}

	public void oeffnenStandard() throws F_Sys_Datei {
		DateiSystem.start(this);
	}

	public void loeschen() throws F_Sys_Datei {
		if(this.file.exists())
			if(!this.file.delete())
				Fehler.datei.da_NichtGeloescht(this.file);
	}

	public void umbenennen(String neu) throws F_Sys_Datei {
		//TODO siehe DateiSystem
		//TODO Darf keinen Slash enthalten!
		Fehler.objekt.wenn_Null(neu);
		File file_neu=this.gElternOrdner().dN(neu).gFile();
		boolean b=this.file.renameTo(file_neu);
		if(!b) throw Fehler.datei.da_NichtUmbenannt(this, neu);
		this.file=file_neu;
	}

	public void verschieben(S_Ordner nach) throws F_Sys_Datei {
		DateiSystem.verschieben(this.gFile(), nach.dN(this.gNameKomplett()).gFile());
	}

	public void kopieren(S_Ordner nach) throws F_Sys_InOut {
		DateiSystem.kopierenDatei(this.gFile(), nach.dN(this.gNameKomplett()).gFile());
	}

	public void anlegen() throws F_Sys_InOut {
		boolean ok=false;
		try {
			ok=this.file.createNewFile();
		}
		catch(IOException e) {
			Fehler.weitergeben(e, "Fehler beim anlegen der Datei");
			return;
		}
		if(!ok)
			Fehler.datei.da_Zugriffsfehler("Datei existiert vmtl. bereits", this.gPfadKomplett());
	}

	public String gPfad() {
		return this.file.getParent();
	}

	public S_Ordner gElternOrdner() {
		try {
			return new DSOrdner(this.file.getParent());
		}
		catch(F_Sys_Datei e) {
			throw Fehler.sonstige.da_Unmoeglich(e);
		}
	}

	public boolean istOrdner() {
		return false;
	}

}
